<script setup>
/**
 * 表文档查看器组件
 * 用于动态加载和展示表文档内容
 * 支持实时监听文件变化，提供搜索和分组功能
 */
import { ref, onMounted, computed, watch, onUnmounted, inject } from 'vue'
import { useData } from 'vitepress'
import CopyButton from './CopyButton.vue'
import { marked } from 'marked'
import CodeBlock from './CodeBlock.vue'
import axios from 'axios'

// 状态变量
const loading = ref(true)
const error = ref(null)
const tables = ref([])
const searchQuery = ref('')
const selectedTable = ref('')
const tableContent = ref('')
const contentLoading = ref(false)
const modifiedTables = ref([])
const monitorStatus = ref('active')
const activeGroups = ref([]) // 修复activeGroups未定义问题
const expandedGroups = ref({})
const docsDir = ref('')
const showSuggestions = ref(false)
const activeSuggestionIndex = ref(-1)

// 获取当前路由信息
const { page } = useData()

// 监听表名变化
let monitorInterval = null
let lastCheckTime = Date.now()

// 过滤后的表格
const filteredTables = computed(() => {
  if (!searchQuery.value) return tables.value
  
  return tables.value.filter(table => 
    table.name.toLowerCase().includes(searchQuery.value.toLowerCase())
  )
})

// 获取表格分组
const tableGroups = computed(() => {
  const groups = {}
  const filteredTables = tables.value.filter(table => 
    table.name.toLowerCase().includes(searchQuery.value.toLowerCase())
  )
  
  for (const table of filteredTables) {
    // 按首字母或自定义分组
    const groupName = getTableGroupName(table.name)
    
    if (!groups[groupName]) {
      groups[groupName] = []
    }
    groups[groupName].push(table)
  }
  
  // 按分组名称排序
  return Object.keys(groups).sort().map(key => ({
    name: key,
    tables: groups[key].sort()
  }))
})

// 获取表格分组名称
function getTableGroupName(tableName) {
  // 可以根据规则进行自定义分组，这里简单按首字母
  // 例如: 以数字开头的归为一组，以字母开头的归为各自字母组
  const firstChar = tableName.charAt(0).toUpperCase()
  if (/\d/.test(firstChar)) {
    return '0-9'
  }
  return firstChar
}

// 渲染Markdown内容
const renderedContent = computed(() => {
  if (!tableContent.value) return ''
  return marked(tableContent.value)
})

// 搜索建议列表
const searchSuggestions = computed(() => {
  if (!searchQuery.value || searchQuery.value.length < 1) return []
  
  const query = searchQuery.value.toLowerCase()
  return tables.value
    .filter(table => table.name.toLowerCase().includes(query))
    .slice(0, 5) // 最多显示5个建议
})

// 处理建议点击
function handleSuggestionClick(table) {
  searchQuery.value = table.name
  showSuggestions.value = false
  selectTable(table.name)
}

// 处理输入框焦点
function handleSearchFocus() {
  showSuggestions.value = true
}

// 处理输入框失去焦点
function handleSearchBlur() {
  // 延迟隐藏建议，以便可以点击建议项
  setTimeout(() => {
    showSuggestions.value = false
  }, 200)
}

// 处理键盘导航
function handleSearchKeydown(event) {
  if (!showSuggestions.value || searchSuggestions.value.length === 0) return
  
  switch (event.key) {
    case 'ArrowDown':
      event.preventDefault()
      activeSuggestionIndex.value = (activeSuggestionIndex.value + 1) % searchSuggestions.value.length
      break
    case 'ArrowUp':
      event.preventDefault()
      activeSuggestionIndex.value = activeSuggestionIndex.value <= 0 
        ? searchSuggestions.value.length - 1 
        : activeSuggestionIndex.value - 1
      break
    case 'Enter':
      if (activeSuggestionIndex.value >= 0) {
        event.preventDefault()
        handleSuggestionClick(searchSuggestions.value[activeSuggestionIndex.value])
      }
      break
    case 'Escape':
      event.preventDefault()
      showSuggestions.value = false
      break
  }
}

// 初始化
onMounted(() => {
  // 尝试从URL获取文档目录
  const pathSegments = window.location.pathname.split('/')
  let basePath = ''
  
  // 查找docs目录的位置
  const docsIndex = pathSegments.findIndex(segment => segment === 'docs')
  if (docsIndex !== -1) {
    // 构建到docs根目录的相对路径
    const upCount = pathSegments.length - docsIndex - 1
    basePath = upCount > 0 ? '../'.repeat(upCount) : './'
  } else {
    // 假设在开发环境中
    basePath = '/'
  }
  
  docsDir.value = `${basePath}tables`
  loadTables()
  startMonitoring() // 确保监控启动
  
  // 如果URL中有表名，自动选择该表
  const tableName = window.location.hash.substring(1)
  if (tableName) {
    // 在表格加载完成后再次检查
    const checkTableLoaded = () => {
      if (tables.value.length > 0) {
        // 尝试精确匹配
        const exactMatch = tables.value.find(t => t.name === tableName)
        if (exactMatch) {
          selectTable(exactMatch.name)
        } else {
          // 尝试包含匹配
          const containMatch = tables.value.find(t => 
            t.name.toLowerCase().includes(tableName.toLowerCase()))
          if (containMatch) {
            selectTable(containMatch.name)
          }
        }
      } else {
        // 表格尚未加载完成，延迟检查
        setTimeout(checkTableLoaded, 500)
      }
    }
    
    checkTableLoaded()
  }
})

/**
 * 获取所有表信息
 * 从API端点加载表格列表
 */
async function loadTables() {
  try {
    loading.value = true
    error.value = null
    
    try {
      // 使用fetch代替axios，并且使用正确的API端点
      const response = await fetch('/api/tables')
      
      // 检查响应是否为JSON格式
      const contentType = response.headers.get('content-type')
      if (!contentType || !contentType.includes('application/json')) {
        console.warn('API响应不是JSON格式:', contentType)
        throw new Error('API响应格式错误')
      }
      
      if (!response.ok) {
        throw new Error('获取表信息失败: ' + response.status)
      }
      
      const data = await response.json()
      
      if (data.error) {
        throw new Error(data.error)
      }
      
      // 确保返回的数据包含tables数组
      if (!data.tables || !Array.isArray(data.tables)) {
        throw new Error('API返回的数据格式不正确')
      }
      
      tables.value = data.tables
    } catch (apiErr) {
      console.error('API加载表格失败，使用默认数据:', apiErr)
      
      // 使用内置默认数据
      tables.value = [
        {
          name: "sys_user",
          description: "用户表",
          path: "/tables/sys_user.md",
          updateTime: "2024-03-27T12:00:00Z"
        },
        {
          name: "sys_role",
          description: "角色表",
          path: "/tables/sys_role.md",
          updateTime: "2024-03-27T12:00:00Z"
        },
        {
          name: "sys_menu",
          description: "菜单表",
          path: "/tables/sys_menu.md",
          updateTime: "2024-03-27T12:00:00Z"
        },
        {
          name: "sys_dept",
          description: "部门表",
          path: "/tables/sys_dept.md",
          updateTime: "2024-03-27T12:00:00Z"
        },
        {
          name: "sys_config",
          description: "配置表",
          path: "/tables/sys_config.md",
          updateTime: "2024-03-27T12:00:00Z"
        }
      ]
    }
    
    // 初始打开第一个分组
    if (tableGroups.value.length > 0 && activeGroups.value.length === 0) {
      activeGroups.value = [tableGroups.value[0].name]
    }
    
    // 默认展开所有分组
    const groups = {}
    for (const table of tables.value) {
      const groupName = getTableGroupName(table.name)
      groups[groupName] = true
    }
    expandedGroups.value = groups
    
    loading.value = false
  } catch (err) {
    loading.value = false
    error.value = err.message || '获取表信息失败'
    console.error('获取表信息错误:', err)
  }
}

/**
 * 选择表格
 * @param {Object} table 表格对象
 */
async function selectTable(tableName) {
  try {
    if (selectedTable.value === tableName) return
    
    selectedTable.value = tableName
    contentLoading.value = true
    tableContent.value = ''
    
    // 更新URL hash，方便分享
    window.location.hash = tableName
    
    await loadTableContent(tableName)
  } catch (err) {
    contentLoading.value = false
    console.error('获取表内容错误:', err)
    tableContent.value = `加载表内容出错: ${err.message}`
  }
}

/**
 * 开始监控表格变化
 * 每5秒检查一次文件变化
 */
function startMonitoring() {
  if (monitorInterval) {
    clearInterval(monitorInterval)
  }
  
  monitorInterval = setInterval(checkForChanges, 5000)
  monitorStatus.value = 'active'
}

/**
 * 检查表格文件变化
 * 对比现有表格和最新表格列表
 */
async function checkForChanges() {
  try {
    try {
      const response = await fetch('/api/tables')
      if (!response.ok) {
        console.warn('检查表格更新失败:', response.status)
        return
      }
      
      const data = await response.json()
      if (!data.tables) {
        console.warn('检查表格更新返回格式错误')
        return
      }
      
      const newTables = data.tables.map(t => t.name)
      const oldTables = tables.value.map(t => t.name)
      
      // 检查是否有新增或删除的表
      if (newTables.length !== oldTables.length || 
          JSON.stringify(newTables.sort()) !== JSON.stringify(oldTables.sort())) {
        tables.value = data.tables
        monitorStatus.value = 'updated'
        
        // 5秒后恢复正常状态
        setTimeout(() => {
          monitorStatus.value = 'active'
        }, 5000)
        
        return
      }
    } catch (err) {
      console.warn('监控表格变化网络错误，忽略:', err)
      return
    }
    
    // 如果当前有选中的表，检查内容是否有更新
    if (selectedTable.value) {
      try {
        const response = await fetch(`/raw-tables/${selectedTable.value}.md`)
        if (!response.ok) return
        
        const content = await response.text()
        
        if (content !== tableContent.value) {
          // 表内容已更新
          tableContent.value = content
          
          // 添加到已修改表格列表
          if (!modifiedTables.value.includes(selectedTable.value)) {
            modifiedTables.value.push(selectedTable.value)
          }
          
          monitorStatus.value = 'updated'
          
          // 5秒后恢复正常状态
          setTimeout(() => {
            monitorStatus.value = 'active'
          }, 5000)
        }
      } catch (err) {
        console.warn('检查表内容变化网络错误，忽略:', err)
      }
    }
  } catch (err) {
    console.error('监控表格变化错误(忽略):', err)
  }
}

/**
 * 手动刷新所有表格数据
 */
async function refreshTables() {
  monitorStatus.value = 'refreshing'
  await loadTables()
  
  if (selectedTable.value) {
    const table = tables.value.find(t => t.name === selectedTable.value)
    if (table) {
      await selectTable(table.name)
    }
  }
  
  monitorStatus.value = 'active'
}

/**
 * 清除当前选中的表格
 */
function clearSelection() {
  selectedTable.value = ''
  tableContent.value = ''
  window.location.hash = ''
}

/**
 * 切换表格分组的展开/折叠状态
 */
function toggleGroup(groupName) {
  expandedGroups.value[groupName] = !expandedGroups.value[groupName]
}

// 组件销毁时清除监控
onUnmounted(() => {
  if (monitorInterval) {
    clearInterval(monitorInterval)
  }
})

/**
 * 加载表格内容
 */
async function loadTableContent(tableName) {
  contentLoading.value = true
  try {
    if (!tableName) {
      throw new Error('表名为空')
    }
    
    // 确保文件名格式正确
    const fileName = tableName.endsWith('.md') ? tableName : `${tableName}.md`
    
    // 使用fetch获取原始表格内容
    try {
      console.log(`尝试加载表格文件: ${fileName}`)
      const response = await fetch(`/raw-tables/${fileName}`)
      
      // 检查内容类型
      const contentType = response.headers.get('content-type')
      if (contentType && contentType.includes('text/html')) {
        console.warn('返回了HTML而不是Markdown:', contentType)
        throw new Error('服务器返回了HTML而不是预期的Markdown文件')
      }
      
      if (!response.ok) {
        throw new Error(`获取表格内容失败: ${response.status} ${response.statusText}`)
      }
      
      const content = await response.text()
      
      // 检查内容是否为HTML
      if (content.includes('<!DOCTYPE') || content.includes('<html')) {
        console.warn('内容疑似HTML而非Markdown:', content.substring(0, 100))
        throw new Error('内容看起来像HTML而不是Markdown')
      }
      
      // 检查内容是否为空
      if (!content.trim()) {
        throw new Error('表格内容为空')
      }
      
      tableContent.value = content
      console.log(`成功加载表格内容, 长度=${content.length}字节`)
    } catch (err) {
      console.error('获取表格内容网络错误:', err)
      
      // 使用内置demo数据
      if (tableName === 'sys_user') {
        tableContent.value = `# sys_user 用户表

## 表信息

| 表名      | 描述   | 所属模块 | 备注         |
|-----------|--------|----------|--------------|
| sys_user  | 用户表 | 系统管理 | 存储系统用户信息 |

## 字段详情

| 序号 | 字段名      | 数据类型     | 长度 | 允许NULL | 默认值 | 描述       | 备注                         |
|------|-------------|--------------|------|----------|--------|------------|------------------------------|
| 1    | user_id     | bigint       | 20   | 否       | -      | 用户ID     | 主键                         |
| 2    | dept_id     | bigint       | 20   | 是       | NULL   | 部门ID     | 外键关联sys_dept表           |
| 3    | user_name   | varchar      | 30   | 否       | -      | 用户账号   | 登录名，唯一                 |
| 4    | nick_name   | varchar      | 30   | 否       | -      | 用户昵称   | 显示名称                     |
| 5    | user_type   | varchar      | 10   | 是       | 'sys'  | 用户类型   | sys=系统用户，gen=一般用户   |
| 6    | email       | varchar      | 50   | 是       | NULL   | 用户邮箱   | 唯一                         |
| 7    | phone_number| varchar      | 11   | 是       | NULL   | 手机号码   | 唯一                         |
| 8    | gender      | char         | 1    | 是       | '0'    | 用户性别   | 0=男，1=女，2=未知           |
`;
      } else if (tableName === 'sys_role') {
        tableContent.value = `# sys_role 角色表

## 表信息

| 表名      | 描述   | 所属模块 | 备注         |
|-----------|--------|----------|--------------|
| sys_role  | 角色表 | 系统管理 | 存储系统角色信息 |

## 字段详情

| 序号 | 字段名      | 数据类型     | 长度 | 允许NULL | 默认值 | 描述       | 备注                         |
|------|-------------|--------------|------|----------|--------|------------|------------------------------|
| 1    | role_id     | bigint       | 20   | 否       | -      | 角色ID     | 主键                         |
| 2    | role_name   | varchar      | 30   | 否       | -      | 角色名称   | 唯一                         |
| 3    | role_key    | varchar      | 100  | 否       | -      | 角色权限   | 唯一                         |
| 4    | role_sort   | int          | 4    | 否       | 0      | 显示顺序   | -                            |
| 5    | status      | char         | 1    | 否       | '0'    | 状态       | 0=正常，1=停用               |
`;
      } else if (tableName === 'sys_menu') {
        tableContent.value = `# sys_menu 菜单表

## 表信息

| 表名      | 描述   | 所属模块 | 备注         |
|-----------|--------|----------|--------------|
| sys_menu  | 菜单表 | 系统管理 | 存储系统菜单信息 |

## 字段详情

| 序号 | 字段名      | 数据类型     | 长度 | 允许NULL | 默认值 | 描述       | 备注                         |
|------|-------------|--------------|------|----------|--------|------------|------------------------------|
| 1    | menu_id     | bigint       | 20   | 否       | -      | 菜单ID     | 主键                         |
| 2    | menu_name   | varchar      | 50   | 否       | -      | 菜单名称   | -                            |
| 3    | parent_id   | bigint       | 20   | 是       | 0      | 父菜单ID   | -                            |
| 4    | order_num   | int          | 4    | 否       | 0      | 显示顺序   | -                            |
| 5    | path        | varchar      | 200  | 是       | ''     | 路由地址   | -                            |
| 6    | component   | varchar      | 255  | 是       | NULL   | 组件路径   | -                            |
| 7    | menu_type   | char         | 1    | 否       | -      | 菜单类型   | M=目录，C=菜单，F=按钮       |
`;
      } else {
        tableContent.value = `# ${tableName} 表

## 表信息

| 表名 | 描述 | 所属模块 | 备注 |
|------|------|----------|------|
| ${tableName} | ${tableName}表 | 系统模块 | 演示数据 |

## 字段详情

| 序号 | 字段名      | 数据类型     | 长度 | 允许NULL | 默认值 | 描述     | 备注   |
|------|-------------|--------------|------|----------|--------|----------|--------|
| 1    | id          | bigint       | 20   | 否       | -      | 主键ID   | 自增   |
| 2    | name        | varchar      | 100  | 否       | -      | 名称     | -      |
| 3    | status      | char         | 1    | 否       | '0'    | 状态     | 0=正常,1=停用 |
| 4    | create_time | datetime     | -    | 否       | CURRENT_TIMESTAMP | 创建时间 | - |
| 5    | update_time | datetime     | -    | 是       | NULL   | 更新时间 | - |

## 演示数据

这是${tableName}表的演示文档，实际数据请参考数据库或接口文档。
`;
      }
      console.log('使用内置演示数据:', tableName);
    }
  } catch (error) {
    console.error('加载表格内容失败:', error)
    tableContent.value = `加载表格内容失败: ${error.message}`
  } finally {
    contentLoading.value = false
  }
}

// 监听搜索变化
watch(searchQuery, () => {
  activeSuggestionIndex.value = -1
  showSuggestions.value = searchQuery.value.length > 0
  
  // 当搜索内容变化时，自动展开所有分组以方便查看
  for (const group of tableGroups.value) {
    expandedGroups.value[group.name] = true
  }
})
</script>

<template>
  <div class="table-viewer">
    <!-- 表格选择面板 -->
    <div class="table-picker">
      <div class="table-picker-header">
        <h2>数据表文档</h2>
        <div class="search-box">
          <input 
            type="text" 
            v-model="searchQuery" 
            placeholder="搜索表名..."
            class="search-input"
            @focus="handleSearchFocus"
            @blur="handleSearchBlur"
            @keydown="handleSearchKeydown"
          />
          <div v-if="showSuggestions && searchSuggestions.length > 0" class="search-suggestions">
            <div 
              v-for="(suggestion, index) in searchSuggestions" 
              :key="suggestion.name"
              class="suggestion-item"
              :class="{ active: index === activeSuggestionIndex }"
              @mousedown="handleSuggestionClick(suggestion)"
              @mouseover="activeSuggestionIndex = index"
            >
              <span class="suggestion-name">{{ suggestion.name }}</span>
              <span v-if="suggestion.description" class="suggestion-desc">{{ suggestion.description }}</span>
            </div>
          </div>
        </div>
      </div>
      
      <div v-if="loading" class="loading">
        加载表信息中...
      </div>
      
      <div v-else-if="error" class="error">
        {{ error }}
      </div>
      
      <div v-else class="table-list">
        <div v-if="filteredTables.length === 0" class="no-result">
          没有找到匹配的表
        </div>
        
        <template v-else>
          <!-- 表格分组列表 -->
          <div v-for="group in tableGroups" :key="group.name" class="table-group">
            <div 
              class="table-group-header" 
              @click="toggleGroup(group.name)"
            >
              <span class="group-name">{{ group.name }}</span>
              <span class="count">({{ group.tables.length }})</span>
              <span class="group-toggle">
                {{ expandedGroups[group.name] ? '▼' : '▶' }}
              </span>
            </div>
            
            <div 
              v-if="expandedGroups[group.name]" 
              class="table-group-items"
            >
              <div 
                v-for="table in group.tables" 
                :key="table.name"
                class="table-item"
                :class="{ active: selectedTable === table.name }"
                @click="selectTable(table.name)"
              >
                <span class="table-name">{{ table.name }}</span>
                <span 
                  v-if="modifiedTables.includes(table.name)" 
                  class="modified-badge"
                >更新</span>
              </div>
            </div>
          </div>
        </template>
      </div>
      
      <div class="monitor-status">
        <span :class="['status-indicator', monitorStatus]"></span>
        <span class="status-text">
          {{ monitorStatus === 'active' ? '实时监控中' : 
             monitorStatus === 'updated' ? '检测到更新' : 
             monitorStatus === 'refreshing' ? '刷新中...' :
             monitorStatus === 'error' ? '监控错误' : '监控已停止' }}
        </span>
        <button 
          class="refresh-button"
          @click="refreshTables"
          :disabled="monitorStatus === 'refreshing'"
        >
          刷新
        </button>
      </div>
    </div>
    
    <!-- 表格内容显示区域 -->
    <div class="table-content">
      <div v-if="!selectedTable" class="empty-state">
        <div class="empty-icon">📋</div>
        <div class="empty-text">请从左侧选择一个表格查看文档</div>
      </div>
      
      <template v-else>
        <div class="table-detail-header">
          <h2 class="table-title">
            {{ selectedTable }}
            <span class="table-badge">表结构</span>
          </h2>
          <div class="table-actions">
            <CopyButton 
              :content="tableContent" 
              label="复制" 
              successLabel="已复制!"
              title="复制表格文档到剪贴板"
              @copy-success="() => {}"
              @copy-error="(err) => console.error('复制错误:', err)"
            />
            <button 
              class="close-button"
              @click="clearSelection"
              title="关闭当前表格"
            >
              ×
            </button>
          </div>
        </div>
        
        <div v-if="contentLoading" class="content-loading">
          加载内容中...
        </div>
        
        <div v-else class="table-detail-content">
          <CodeBlock
            :code="tableContent"
            language="markdown"
            :copy-enabled="true"
            label="Markdown"
            :show-line-numbers="false"
            max-height="calc(100vh - 250px)"
          />
        </div>
      </template>
    </div>
  </div>
</template>

<style scoped>
.table-viewer {
  display: flex;
  height: calc(100vh - 180px);
  min-height: 500px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  overflow: hidden;
  background-color: var(--vp-c-bg);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.table-picker {
  width: 240px;
  min-width: 180px;
  border-right: 1px solid var(--vp-c-divider);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background-color: var(--vp-c-bg-alt);
}

.table-picker-header {
  padding: 16px;
  border-bottom: 1px solid var(--vp-c-divider);
  background-color: var(--vp-c-bg);
}

.table-picker-header h2 {
  margin: 0 0 12px 0;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--vp-c-brand);
}

.search-box {
  position: relative;
}

.search-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 4px;
  font-size: 0.9rem;
  background-color: var(--vp-c-bg);
  color: var(--vp-c-text-1);
  transition: all 0.3s;
}

.search-input:focus {
  outline: none;
  border-color: var(--vp-c-brand);
  box-shadow: 0 0 0 2px rgba(var(--vp-c-brand-rgb), 0.1);
}

.search-suggestions {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background-color: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  border-radius: 4px;
  max-height: 200px;
  overflow-y: auto;
  z-index: 100;
  margin-top: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.suggestion-item {
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid var(--vp-c-divider-light);
}

.suggestion-item:last-child {
  border-bottom: none;
}

.suggestion-item.active,
.suggestion-item:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
}

.suggestion-name {
  font-weight: 500;
  color: var(--vp-c-text-1);
}

.suggestion-desc {
  font-size: 0.8rem;
  color: var(--vp-c-text-2);
  margin-top: 2px;
}

.table-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0;
}

.table-group {
  margin-bottom: 4px;
}

.table-group-header {
  display: flex;
  align-items: center;
  padding: 8px 16px;
  cursor: pointer;
  font-weight: 600;
  color: var(--vp-c-text-1);
  user-select: none;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.table-group-header:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
}

.group-name {
  flex: 1;
}

.count {
  color: var(--vp-c-text-2);
  font-size: 0.85rem;
  margin-right: 8px;
  background-color: var(--vp-c-bg);
  padding: 2px 6px;
  border-radius: 10px;
  font-weight: normal;
}

.group-toggle {
  font-size: 0.8rem;
  width: 16px;
  text-align: center;
  transition: transform 0.2s;
}

.table-group-items {
  max-height: 300px;
  overflow-y: auto;
  margin-left: 8px;
}

.table-item {
  display: flex;
  align-items: center;
  padding: 8px 16px 8px 24px;
  cursor: pointer;
  font-size: 0.9rem;
  border-left: 2px solid transparent;
  position: relative;
  border-radius: 0 4px 4px 0;
  transition: all 0.2s;
  margin: 2px 0;
}

.table-item:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.05);
}

.table-item.active {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
  border-left-color: var(--vp-c-brand);
  font-weight: 600;
  color: var(--vp-c-brand);
}

.table-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.modified-badge {
  display: inline-block;
  font-size: 0.7rem;
  background-color: var(--vp-c-brand);
  color: white;
  padding: 2px 6px;
  border-radius: 10px;
  margin-left: 8px;
  font-weight: normal;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    opacity: 0.6;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0.6;
  }
}

.monitor-status {
  padding: 12px 16px;
  border-top: 1px solid var(--vp-c-divider);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: var(--vp-c-bg);
}

.status-indicator {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  margin-right: 8px;
  position: relative;
}

.status-indicator.active {
  background-color: var(--vp-c-green);
  box-shadow: 0 0 0 4px rgba(var(--vp-c-green-rgb), 0.2);
}

.status-indicator.updated {
  background-color: var(--vp-c-yellow);
  box-shadow: 0 0 0 4px rgba(var(--vp-c-yellow-rgb), 0.2);
}

.status-indicator.refreshing {
  background-color: var(--vp-c-gray-light-3);
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.status-indicator.error {
  background-color: var(--vp-c-red);
  box-shadow: 0 0 0 4px rgba(var(--vp-c-red-rgb), 0.2);
}

.status-text {
  font-size: 0.85rem;
  color: var(--vp-c-text-2);
}

.refresh-button {
  background: none;
  border: none;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--vp-c-brand);
  border-radius: 4px;
  transition: all 0.2s;
}

.refresh-button:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
}

.refresh-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.table-content {
  flex: 1;
  overflow-y: auto;
  padding: 0;
  position: relative;
  min-width: 0; /* 确保弹性布局中内容不会溢出 */
  background-color: var(--vp-c-bg);
}

.table-detail-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: var(--vp-c-bg);
  padding: 16px 24px;
  border-bottom: 1px solid var(--vp-c-divider);
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.table-title {
  margin: 0;
  font-size: 1.2rem;
  display: flex;
  align-items: center;
  gap: 8px;
}

.table-badge {
  background-color: var(--vp-c-brand);
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.8rem;
  font-weight: normal;
}

.table-actions {
  display: flex;
  gap: 8px;
}

.close-button {
  background: none;
  border: none;
  padding: 4px 8px;
  cursor: pointer;
  font-size: 1.2rem;
  color: var(--vp-c-text-2);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.close-button:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
  color: var(--vp-c-brand);
}

.content-loading {
  padding: 40px 20px;
  text-align: center;
  color: var(--vp-c-text-2);
  font-size: 0.9rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 200px;
}

.content-loading::after {
  content: '';
  display: block;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid var(--vp-c-divider);
  border-top-color: var(--vp-c-brand);
  animation: spin 1s linear infinite;
  margin-top: 16px;
}

.empty-state {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
  padding: 32px;
  text-align: center;
  color: var(--vp-c-text-2);
}

.empty-icon {
  font-size: 4rem;
  margin-bottom: 16px;
  color: var(--vp-c-text-3);
}

.empty-text {
  margin: 0;
  color: var(--vp-c-text-2);
  font-size: 1.1rem;
  max-width: 400px;
}

.loading, .error, .no-result {
  padding: 20px;
  text-align: center;
  color: var(--vp-c-text-2);
  font-size: 0.9rem;
}

.error {
  color: var(--vp-c-red);
  background-color: rgba(var(--vp-c-red-rgb), 0.1);
  border-radius: 4px;
  padding: 16px;
  margin: 16px;
}

.table-detail-content {
  padding: 0;
}

/* 适配暗黑模式和亮色模式 */
@media (prefers-color-scheme: dark) {
  .table-viewer {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  }
}

@media (max-width: 768px) {
  .table-viewer {
    flex-direction: column;
    height: auto;
  }
  
  .table-picker {
    width: 100%;
    max-height: 300px;
  }
  
  .table-content {
    height: calc(100vh - 400px);
  }
}
</style> 